package tests

import (
	"fmt"
	"os"
	"strconv"
	"time"
)

// TestConfig 测试配置
type TestConfig struct {
	// 数据库配置
	Database DatabaseConfig

	// 测试行为配置
	Behavior BehaviorConfig

	// 性能测试配置
	Performance PerformanceConfig
}

// DatabaseConfig 数据库测试配置
type DatabaseConfig struct {
	Host            string
	Port            int
	User            string
	Password        string
	SSLMode         string
	MaxConnections  int
	ConnMaxLifetime time.Duration
	CleanupTimeout  time.Duration
}

// BehaviorConfig 测试行为配置
type BehaviorConfig struct {
	SkipIntegrationTests bool
	SkipE2ETests         bool
	SkipPerformanceTests bool
	VerboseOutput        bool
	StopOnFirstFailure   bool
	TestTimeout          time.Duration
}

// PerformanceConfig 性能测试配置
type PerformanceConfig struct {
	MaxResponseTime time.Duration
	MinThroughput   int
	ConcurrentUsers int
	TestDuration    time.Duration
	WarmupDuration  time.Duration
	DatasetSize     int
}

// DefaultTestConfig 默认测试配置
func DefaultTestConfig() *TestConfig {
	return &TestConfig{
		Database: DatabaseConfig{
			Host:            getEnvOrDefault("TEST_DB_HOST", "localhost"),
			Port:            getEnvAsIntOrDefault("TEST_DB_PORT", 5432),
			User:            getEnvOrDefault("TEST_DB_USER", "postgres"),
			Password:        getEnvOrDefault("TEST_DB_PASSWORD", "Abc@123456"),
			SSLMode:         getEnvOrDefault("TEST_DB_SSLMODE", "disable"),
			MaxConnections:  getEnvAsIntOrDefault("TEST_DB_MAX_CONNECTIONS", 10),
			ConnMaxLifetime: time.Hour,
			CleanupTimeout:  30 * time.Second,
		},
		Behavior: BehaviorConfig{
			SkipIntegrationTests: getEnvAsBoolOrDefault("SKIP_INTEGRATION_TESTS", false),
			SkipE2ETests:         getEnvAsBoolOrDefault("SKIP_E2E_TESTS", false),
			SkipPerformanceTests: getEnvAsBoolOrDefault("SKIP_PERFORMANCE_TESTS", false),
			VerboseOutput:        getEnvAsBoolOrDefault("VERBOSE_OUTPUT", false),
			StopOnFirstFailure:   getEnvAsBoolOrDefault("STOP_ON_FIRST_FAILURE", false),
			TestTimeout:          time.Duration(getEnvAsIntOrDefault("TEST_TIMEOUT", 300)) * time.Second,
		},
		Performance: PerformanceConfig{
			MaxResponseTime: 100 * time.Millisecond,
			MinThroughput:   1000, // requests per second
			ConcurrentUsers: getEnvAsIntOrDefault("CONCURRENT_USERS", 100),
			TestDuration:    time.Duration(getEnvAsIntOrDefault("PERF_TEST_DURATION", 60)) * time.Second,
			WarmupDuration:  10 * time.Second,
			DatasetSize:     getEnvAsIntOrDefault("DATASET_SIZE", 1000),
		},
	}
}

// getEnvOrDefault 获取环境变量或默认值
func getEnvOrDefault(key, defaultValue string) string {
	if value := os.Getenv(key); value != "" {
		return value
	}
	return defaultValue
}

// getEnvAsIntOrDefault 获取环境变量作为整数或默认值
func getEnvAsIntOrDefault(key string, defaultValue int) int {
	if value := os.Getenv(key); value != "" {
		if intValue, err := strconv.Atoi(value); err == nil {
			return intValue
		}
	}
	return defaultValue
}

// getEnvAsBoolOrDefault 获取环境变量作为布尔值或默认值
func getEnvAsBoolOrDefault(key string, defaultValue bool) bool {
	if value := os.Getenv(key); value != "" {
		if boolValue, err := strconv.ParseBool(value); err == nil {
			return boolValue
		}
	}
	return defaultValue
}

// IsCI 检查是否在CI环境中运行
func (c *TestConfig) IsCI() bool {
	return os.Getenv("CI") != ""
}

// ShouldRunIntegrationTests 是否应该运行集成测试
func (c *TestConfig) ShouldRunIntegrationTests() bool {
	return !c.Behavior.SkipIntegrationTests
}

// ShouldRunE2ETests 是否应该运行E2E测试
func (c *TestConfig) ShouldRunE2ETests() bool {
	return !c.Behavior.SkipE2ETests
}

// ShouldRunPerformanceTests 是否应该运行性能测试
func (c *TestConfig) ShouldRunPerformanceTests() bool {
	return !c.Behavior.SkipPerformanceTests
}

// GetDatabaseDSN 获取数据库连接字符串
func (c *TestConfig) GetDatabaseDSN(dbName string) string {
	return fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
		c.Database.Host,
		c.Database.Port,
		c.Database.User,
		c.Database.Password,
		dbName,
		c.Database.SSLMode,
	)
}
